﻿using System;
using System.Threading;
using System.Text;

class FallingRocks
{
    static void Main()
    {
        bool isAlive = true;
        int speed = 150;
        int row = 0;
        int dwarfCol = Console.WindowWidth / 2 - 1;
        int index = 0;
        int points = 0;
        string currentLine;
        string[] screenLines = new string[24];
        Console.CursorVisible = false;
        for (int i = 0; i < 24; i++)
        {
            screenLines[i] = EmptyLine();
        }
        Console.SetCursorPosition(dwarfCol, 23);
        Console.WriteLine("(0)");

        do
        {
            if (Console.KeyAvailable)                               //Dwarf move
            {
                ConsoleKeyInfo userInput = Console.ReadKey();
                if (userInput.Key == ConsoleKey.LeftArrow)          //goes Reft
                {

                    if (dwarfCol > 0)
                    {
                        dwarfCol -= 1;
                    }
                }
                if (userInput.Key == ConsoleKey.RightArrow)         //goes Right
                {
                    if (dwarfCol <= Console.WindowWidth - 5)
                    {
                        dwarfCol += 1;
                    }
                }
                if (Console.KeyAvailable)                           //Prevention of unwanted movements
                {
                    do
                    {
                        Console.ReadKey();
                    } while (Console.KeyAvailable);

                }
            }
            screenLines[index] = Line();                        // Generate new line
            for (int l = 0; l < 24; l++)
            {
                Console.SetCursorPosition(0, l);
                currentLine = screenLines[row];
                if (l == 23)                                     // On collision line
                {
                    int len = currentLine.Length - 1;
                    for (int p = 0; p < len; p++)
                    {
                        if (currentLine[len - p] != ' ')
                        {
                            if (len - p == dwarfCol || len - p == dwarfCol + 1 || len - p == dwarfCol + 2)
                            {
                                isAlive = false;
                            }
                        }
                    }
                    currentLine = BottomLine(dwarfCol, screenLines[row]);   //Insert Dwarf in bottom line
                }
                Console.WriteLine(currentLine);
                row--;
                if (row == -1)
                {
                    row = 23;
                } 
             }
            index++;
            if (index == 24) 
            {
                index = 0;
            }
            row = index;
            points += 5;
            if (points % 300 == 0)
            {
                speed -= 20;
            }
            Thread.Sleep(speed);
            Console.Clear();
        } while (isAlive);

        Console.SetCursorPosition(Console.WindowWidth / 2 - 8, 7);
        Console.WriteLine("GAME OVER!!!");
        Console.SetCursorPosition(Console.WindowWidth / 2 - 13, 10);
        Console.WriteLine("YOUR SCORE: {0} points", points);
        Console.SetCursorPosition(0, 23);
        // Thread.Sleep(3000);
    }



    //  ------------------------ * Methods * ------------------------  //


    static int Rnd(int Min, int Max)                        //Generate Random number between Min and Max
    {
        Random random = new Random();
        int randomNumber = random.Next(Min, Max);
        return randomNumber;
    }

    static char RockS(int rockNumber)                       // Rock simbol
    {
        char rockSymbol;
        switch (rockNumber)
        {
            case 1: rockSymbol = '^'; break;
            case 2: rockSymbol = '@'; break;
            case 3: rockSymbol = '*'; break;
            case 4: rockSymbol = '&'; break;
            case 5: rockSymbol = '+'; break;
            case 6: rockSymbol = '%'; break;
            case 7: rockSymbol = '$'; break;
            case 8: rockSymbol = '#'; break;
            case 9: rockSymbol = '!'; break;
            case 10: rockSymbol = '.'; break;
            case 11: rockSymbol = ';'; break;
            default: rockSymbol = '*';
                break;
        }
        return rockSymbol;                                  //Create Rock
    }

    static string Rock()
    {
        string rck = new string(RockS(Rnd(1, 12)), Rnd(1, 5));
        return rck;
    }

    static string Line()                                    // Generate line
    {
        StringBuilder ln = new StringBuilder();
        int level = 2;                                      // Number of rocks per row
        ln.Append("");
        int rockCounter = 0;
        for (int i = 1; i <= Console.WindowWidth - ln.Length; i++)
        {
            if (Console.WindowWidth - 1 - ln.Length > 3)
            {
                ln.Append(' ', Rnd(0, Console.WindowWidth - 1 - ln.Length));
            }
            string nextRock = Rock();
            rockCounter++;
            if ((nextRock.Length <= Console.WindowWidth - 1 - ln.Length) && (rockCounter <= level))
            {
                ln.Append(nextRock);
            }
            else
            {
                ln.Append(' ', Console.WindowWidth - 1 - ln.Length);
            }
        }
        string linePrt = ln.ToString();
        return linePrt;
    }

    static string EmptyLine()                                  
    {
        StringBuilder empty = new StringBuilder();
        empty.Append(' ', Console.WindowWidth - 1);
        string linePrt = empty.ToString();
        return linePrt;
    }

    static string BottomLine(int dwarfPosition, string lastLine)        //Print collision line
    {
        StringBuilder ln = new StringBuilder();
        for (int i = 0; i < dwarfPosition; i++)
        {
            ln.Append(lastLine[i]);
        }
        ln.Append("(0)");
        for (int i = dwarfPosition + 3; i < Console.WindowWidth - 1; i++)
        {
            ln.Append(lastLine[i]);
        }
        string linePrt = ln.ToString();
        return linePrt;
    }
}